package com.itheima.appserver.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.Method;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.appserver.config.HuanXinConfig;
import com.itheima.appserver.exception.MyException;
import com.itheima.appserver.exception.ResultError;
import com.itheima.appserver.interceptor.UserThreadLocal;
import com.itheima.appserver.service.TanHuaService;
import com.itheima.commons.constants.Constants;
import com.itheima.commons.pojo.*;
import com.itheima.commons.vo.NearUserVo;
import com.itheima.commons.vo.PageResult;
import com.itheima.commons.vo.TodayBest;
import com.itheima.commons.vo.UserLocationVo;
import com.itheima.interfaces.BaiDuApi;
import com.itheima.interfaces.QuestionApi;
import com.itheima.interfaces.TanHuaApi;
import com.itheima.interfaces.UserInfoApi;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class TanHuaServiceImpl implements TanHuaService {

    @Reference
    private TanHuaApi tanHuaAPI;

    @Reference
    private UserInfoApi userInfoAPI;

    @Reference
    private QuestionApi questionAPI;

    @Autowired
    private RequestService requestService;

    @Autowired
    private HuanXinConfig huanXinConfig;

    @Reference
    private BaiDuApi baiDuApi;

    @Autowired
    private RedisTemplate<String,String> redisTemplate;

    @Override
    public TodayBest todayBest() {
        //校验token是否未失效
        //获取用户id
        Long toUserId = UserThreadLocal.getUserId();
        //根据用户id 获得佳人id
        RecommendUser recommendUser = tanHuaAPI.todayBestByToUserId(toUserId);
        //根据佳人id 从user_info中获取数据
        UserInfo userInfoByUserId = userInfoAPI.findUserInfoByUserId(recommendUser.getUserId());

        if (ObjectUtil.isEmpty(userInfoByUserId)) {
            throw new MyException(ResultError.recommendUserIsEmpty());

        }

        TodayBest todayBest = TodayBest.init(userInfoByUserId, recommendUser);
        return todayBest;
    }

    @Override
    public PageResult recommendation(Map<String, Object> map) {
        //校验token是否未失效
        //获取用户id
        Long toUserId = UserThreadLocal.getUserId();
        //通过id 获取相关联的信息
        PageResult pageResult = tanHuaAPI.recommendationAllFriend(MapUtil.getInt(map, "page", 1),
                MapUtil.getInt(map, "pagesize", 5), toUserId);
        List<RecommendUser> items = (List<RecommendUser>) pageResult.getItems();
        if (CollUtil.isEmpty(items)) {
            throw new MyException(ResultError.recommendUserIsEmpty());

        }
        List<Long> userId = CollUtil.getFieldValues(items, "userId", Long.class);
        //根据获取到的id 寻找朋友信息
        UserInfo userInfo = new UserInfo();
        userInfo.setSex(MapUtil.get(map, "gender", String.class));
        userInfo.setAge(MapUtil.get(map, "age", Integer.class));
        userInfo.setCity(MapUtil.get(map, "city", String.class));


        Map<Long, UserInfo> userInfoListByUserIds = userInfoAPI.findUserListByUserIds(userInfo, userId);
        List<TodayBest> list = new ArrayList<>();
        if (MapUtil.isEmpty(userInfoListByUserIds)) {
            pageResult.setItems(Collections.emptyList());
            return pageResult;
        }
        for (RecommendUser item : items) {
            TodayBest init = TodayBest.init(userInfoListByUserIds.get(item.getUserId()), item);
            if (ObjectUtil.isNotEmpty(init)) {
                list.add(init);
            }
        }
        pageResult.setItems(list);
        return pageResult;
    }

    @Override
    public TodayBest personalInfo(Long id) {
        //保存访客信息
        Visitors visitors = new Visitors();
        visitors.setId(new ObjectId());
        visitors.setUserId(UserThreadLocal.getUserId());
        visitors.setVisitorUserId(id);
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setScore(0.0D);

        tanHuaAPI.savePersonInfo(visitors);


        //根据用户id 查询用户信息
        UserInfo userInfo = userInfoAPI.findUserInfoByUserId(id);
        //根据用户id 和自己的id 查询心动值
        RecommendUser recommendUser = tanHuaAPI.findScoreByRecommend(id, UserThreadLocal.getUserId());
        TodayBest todayBest = new TodayBest();
        todayBest.setId(userInfo.getUserId());
        todayBest.setAvatar(userInfo.getLogo());
        todayBest.setNickname(userInfo.getNickName());
        todayBest.setGender(userInfo.getSex() == 1 ? "man" : "woman");
        todayBest.setAge(userInfo.getAge());
        todayBest.setTags(userInfo.getTags().split(","));
        todayBest.setFateValue(Convert.toLong(recommendUser.getScore()));

        return todayBest;
    }

    @Override
    public String strangerQuestions(Long id) {
        //根据用户的id 查询用户的问题 没有问题 则返回默认问题
        Question question = questionAPI.strangerQuestions(id);
        if (ObjectUtil.isEmpty(question)) {
            return "你喜欢什么喝什么水";
        }

        return question.getTxt();
    }

    @Override
    public void answerQuestion(Object userId, Object reply) {
        /*
        userId:  申请人ID  登录人的ID                     已知
        huanXinId:  申请人的环信ID  登录人的环信ID          已知
        nickname: 申请人的昵称  登录人的昵称                没有  自己查询数据库
        strangerQuestion:  被申请人设置的问题              没有  自己查询数据库
        reply:  申请人的回答内容                           没有  传递
        被申请人的ID                                      没有  传递
         */
        //查询申请人昵称
        UserInfo userInfo = userInfoAPI.findUserInfoByUserId(UserThreadLocal.getUserId());
        //查询被申请人的问题
        Question question = questionAPI.strangerQuestions(Convert.toLong(userId));
        Map<String, Object> map = new HashMap<>();
        map.put("userId", UserThreadLocal.getUserId());
        map.put("huanXinId", "HX_" + UserThreadLocal.getUserId());
        map.put("nickname", userInfo.getNickName());
        map.put("strangerQuestion", ObjectUtil.isEmpty(question) ? "你喜欢什么颜色" : question.getTxt());
        map.put("reply", reply.toString());
        //发送消息
        HttpResponse response = requestService.execute(huanXinConfig.getUrl() + huanXinConfig.getOrgName() + "/" + huanXinConfig.getAppName() + "/messages",
                JSONUtil.createObj().set("target_type", "users")
                        .set("target", userInfo.getUserId())
                        .set("msg", JSONUtil.createObj().set("type", "txt").set("msg", map)).toString()
                , Method.POST);
        if (!response.isOk()) {
            throw new MyException(ResultError.sendHuanXinMsgError());
        }
    }

    @Override
    public List<NearUserVo> search(String gender, Double distance) {
        //搜索自己的位置
        UserLocationVo userLocationVo = baiDuApi.selectByUserId(UserThreadLocal.getUserId());
        //搜索附近的人
        List<UserLocationVo> userLocationVoList = baiDuApi.selectSearch(userLocationVo.getLatitude(), userLocationVo.getLongitude(), 50, distance);
        //提取用户id
        List<Long> userId = CollUtil.getFieldValues(userLocationVoList, "userId", Long.class);
        //查询用户信息
        Map<Long, UserInfo> publishInfo = userInfoAPI.findUserListByUserIdsByGender(null,userId,gender);
        //封装vo对象返回

        List<NearUserVo> nearUserVos = new ArrayList<>();
        if (CollUtil.isEmpty(publishInfo)){
            return nearUserVos;
        }
        for (UserInfo userInfo : publishInfo.values()) {
            if (userInfo.getUserId().equals(UserThreadLocal.getUserId())){
                continue;
            }
            NearUserVo nearUserVo = new NearUserVo();
            nearUserVo.setUserId(userInfo.getUserId());
            nearUserVo.setAvatar(userInfo.getLogo());
            nearUserVo.setNickname(userInfo.getNickName());
            nearUserVos.add(nearUserVo);
        }
        return nearUserVos;
    }

    @Override
    public List<TodayBest> selectCards() {
        //从Recommend表中根据id 查找userId
        //需要从redis中拿出喜欢和不喜欢用户的id 进行排除
        Set<String> stringSet = redisTemplate.opsForSet().members(Constants.USER_LIKE_KEY + UserThreadLocal.getUserId());
        Set<String> members = redisTemplate.opsForSet().members(Constants.USER_NOT_LIKE_KEY + UserThreadLocal.getUserId());
        //合并
        Collection<String> strings = CollUtil.addAll(stringSet, members);


        List<RecommendUser> recommendUsers = tanHuaAPI.selectByToUserId(UserThreadLocal.getUserId());
        List<Long> userId = CollUtil.getFieldValues(recommendUsers, "userId", Long.class);
        //查询用户信息
        Map<Long, UserInfo> userListByUserIds = userInfoAPI.findUserInfoListByUserIdsByCondition(new UserInfo(), userId,strings);

        List<TodayBest> todayBestList = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUsers) {
            UserInfo userInfo = userListByUserIds.get(recommendUser.getUserId());
            TodayBest todayBest = new TodayBest();
            todayBest.setId(userInfo.getUserId());
            todayBest.setAvatar(userInfo.getLogo());
            todayBest.setNickname(userInfo.getNickName());
            todayBest.setGender(userInfo.getSex() == 1 ? "man" : "woman");
            todayBest.setAge(userInfo.getAge());
            todayBest.setTags(userInfo.getTags().split(","));

            todayBest.setFateValue(Convert.toLong(recommendUser.getScore()));
            todayBestList.add(todayBest);
        }
        return todayBestList;
    }

    @Override
    public void loveCard(Long id) {
        //把对方id 添加到喜欢表中
        UserLike userLike = new UserLike();
        userLike.setId(new ObjectId());
        userLike.setUserId(UserThreadLocal.getUserId());
        userLike.setLikeUserId(id);
        userLike.setCreated(System.currentTimeMillis());

        tanHuaAPI.loveCard(userLike);
        //存进redis中
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY+UserThreadLocal.getUserId(),id.toString());
    }

    @Override
    public void unloveCard(Long id) {
        //把不喜欢人的id存入redis中
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY+UserThreadLocal.getUserId(),id.toString());
    }

}
